using System;
using System.Collections.Generic;

namespace SIP.PN.Modelo.Entidades
{
    public class ProyectoTarea : ProyectoTareaAbstracta
    {
        private Tarea tarea;
        private DateTime fechaInicio;
        private DateTime fechaFinEsperado;
        private DateTime? fechaFinReal;
        private int duracionDias;
        private int porcentajeAvance;
        private string desviadaMotivo;

        private IList<TareaRequisito> requisitos = new List<TareaRequisito>();
        private IList<Asignacion> asignaciones = new List<Asignacion>();
        private IList<EvaluacionTarea> evaluaciones = new List<EvaluacionTarea>();

        public virtual Tarea Tarea
        {
            get { return tarea; }
            set { tarea = value; }
        }

        public virtual DateTime FechaInicio
        {
            get { return fechaInicio; }
            set { fechaInicio = value; }
        }

        public virtual DateTime FechaFinEsperado
        {
            get { return fechaFinEsperado; }
            set { fechaFinEsperado = value; }
        }

        public virtual DateTime? FechaFinReal
        {
            get { return fechaFinReal; }
            set { fechaFinReal = value; }
        }

        public virtual int DuracionDias
        {
            get { return duracionDias; }
            set { duracionDias = value; }
        }

        public virtual int PorcentajeAvance
        {
            get { return porcentajeAvance; }
            set { porcentajeAvance = value; }
        }

        public virtual string DesviadaMotivo
        {
            get { return desviadaMotivo; }
            set { desviadaMotivo = value; }
        }

        public virtual IList<TareaRequisito> Requisitos
        {
            get { return requisitos; }
            set { requisitos = value; }
        }

        public virtual IList<Asignacion> Asignaciones
        {
            get { return asignaciones; }
            set { asignaciones = value; }
        }

        public virtual IList<EvaluacionTarea> Evaluaciones
        {
            get { return evaluaciones; }
            set { evaluaciones = value; }
        }

        #region Requisito

        public virtual TareaRequisito AgregarRequisito(NivelEspecialidad nivelEspecialidad, int cantidad)
        {
            TareaRequisito tr = new TareaRequisito();
            tr.Tarea = this;
            tr.NivelEspecialidad = nivelEspecialidad;
            tr.Cantidad = cantidad;
            requisitos.Add(tr);
            return tr;
        }

        public virtual TareaRequisito ObtenerRequisito(NivelEspecialidad nivelEspecialidad)
        {
            foreach (TareaRequisito item in requisitos)
            {
                if (item.NivelEspecialidad.Codigo.Equals(nivelEspecialidad.Codigo))
                    return item;
            }
            return null;
        }

        public virtual void EliminarRequisito(NivelEspecialidad nivelEspecialidad)
        {
            TareaRequisito tr = ObtenerRequisito(nivelEspecialidad);
            if (tr != null)
            {
                requisitos.Remove(tr);
            }
        }

        public virtual bool CumpleRequisitos()
        {
            foreach (TareaRequisito requisito in Requisitos)
            {
                IList<Asignacion> a = ListarAsignacion(requisito.NivelEspecialidad);
                if (a.Count < requisito.Cantidad)
                    return false;
            }
            return true;
        }

        

        #endregion

        #region Asignacion

        public virtual IList<Asignacion> ListarAsignacion(NivelEspecialidad nivelEspecialidad)
        {
            IList<Asignacion> r = new List<Asignacion>();
            foreach (Asignacion item in asignaciones)
            {
                if (item.OperarioEspecialidad.NivelEspecialidad.Equals(nivelEspecialidad))
                    r.Add(item);
            }
            return r;
        }

        public virtual Asignacion AgregarAsignacion(OperarioEspecialidad operarioEspecialidad)
        {
            if (operarioEspecialidad != null)
            {
                Asignacion a = ObtenerAsignacion(operarioEspecialidad);
                if (a != null)
                    return a;
                
                a = new AsignacionNormal();
                a.Tarea = this;
                a.OperarioEspecialidad = operarioEspecialidad;
                a.FechaAsignacion = DateTime.Now;
                
                asignaciones.Add(a);
                return a;
            }
            return null;
        }

        public virtual Asignacion ReemplazarAsignacion(OperarioEspecialidad operarioEspecialidad, Asignacion asignacion, string motivo)
        {
            AsignacionReemplazo a = new AsignacionReemplazo();
            a.Tarea = this;
            a.OperarioEspecialidad = operarioEspecialidad;
            a.FechaAsignacion = DateTime.Now;
            a.Motivo = motivo;
            //a.Asignacion = asignacion;
            asignacion.Tarea = null;
            asignaciones.Remove(asignacion);
            asignaciones.Add(a);
            return a;
        }

        public virtual Asignacion ObtenerAsignacion(Operario operario)
        {
            foreach (Asignacion item in asignaciones)
            {
                if (item.OperarioEspecialidad.Operario.Equals(operario))
                    return item;
            }
            return null;
        }

        public virtual Asignacion ObtenerAsignacion(OperarioEspecialidad operarioEspecialidad)
        {
            foreach (Asignacion item in asignaciones)
            {
                if (item.OperarioEspecialidad.Equals(operarioEspecialidad))
                    return item;
            }
            return null;
        }

        public virtual Asignacion ObtenerAsignacion(int codigo)
        {
            foreach (Asignacion item in asignaciones)
            {
                if (item.Codigo.Equals(codigo))
                    return item;
            }
            return null;
        }

        public virtual void EliminarAsignacion(int codigo)
        {
            Asignacion item = ObtenerAsignacion(codigo);
            if (item != null)
            {
                asignaciones.Remove(item);
            }
        }

        #endregion

        #region Evaluacion

        public virtual EvaluacionTarea Evaluacion
        {
            get
            {
                if (evaluaciones != null && evaluaciones.Count > 0)
                    return evaluaciones[0];
                return null;
            }
            set
            {
                if (evaluaciones == null)
                    evaluaciones = new List<EvaluacionTarea>();
                if (evaluaciones.Count>0)
                    evaluaciones[0] = value;
                else
                    evaluaciones.Add(value);
            }
        }

        public virtual EvaluacionTarea CrearEvaluacion()
        {
            Evaluacion = new EvaluacionTarea(this);
            Evaluacion.Conceptos = new List<EvaluacionConcepto>();
            Evaluacion.FechaEvaluacion = DateTime.Now;
            return Evaluacion;
        }

        public virtual bool EvaluacionCompleta
        {
            get
            {
                if (Evaluacion==null)
                    return false;
                foreach (Asignacion asignacion in Asignaciones)
                {
                    if (!asignacion.EvaluacionCompleta)
                        return false;
                }
                return true;
            }
        }

        #endregion
    }
}